home *** CD-ROM | disk | FTP | other *** search
- /*
- **
- ** $Id: alaw.c,v 1.2 1995/10/07 02:52:10 chris Exp $
- ** $Revision: 1.2 $
- **
- ** $Filename: developer/alaw.c $
- ** $Author: chris $
- ** $Date: 1995/10/07 02:52:10 $
- **
- ** Convert A-Law to 16-bit and 8-bit linear audio format
- **
- ** COPYRIGHT (C) 1992-1994 BY CHRISTIAN A. WEBER, ZUERICH, SWITZERLAND. ALL
- ** RIGHTS RESERVED. NO PART OF THIS SOFTWARE MAY BE COPIED, REPRODUCED, OR
- ** TRANSMITTED IN ANY FORM OR BY ANY MEANS, WITHOUT THE PRIOR WRITTEN PER-
- ** MISSION OF THE AUTHOR. NO WARRANTY. USE AT YOUR OWN RISK.
- **
- */
-
- #include "os.h"
-
- #define _ALAW
- #include "alaw.h"
-
-
- static S16 *table_alaw_to_16bit;
- static U8 *table_16bit_to_alaw;
-
-
- static S16 ALaw2Sample( S16 code )
- {
- S16 sample;
-
- /* Revert bit order */
- code = (code<<4 & 0xf0) | (code>>4 & 0x0f);
- code = (code<<2 & 0xcc) | (code>>2 & 0x33);
- code = (code<<1 & 0xaa) | (code>>1 & 0x55);
-
- /* Invert even bits: */
- code ^= 0x55;
-
- /* Positive <-> Negative: */
- if (code & 0x80) /* positive A-Law range */
- code &= ~0x80;
- else /* negative A-Law range */
- code = ~code; /* Dasselbe wie -code-1; */
-
- /* Gradient equations (Steigungsgleichungen) */
- if (code >= 112)
- sample = 16384 + (code-112) * 1024;
- else if (code >= 96)
- sample = 8192 + (code-96) * 512;
- else if (code >= 80)
- sample = 4096 + (code-80) * 256;
- else if (code >= 64)
- sample = 2048 + (code-64) * 128;
- else if (code >= 48)
- sample = 1024 + (code-48) * 64;
- else if (code >= 32)
- sample = 512 + (code-32) * 32;
- else if (code >= -32)
- sample = -512 + (code+32) * 16;
- else if (code >= -48)
- sample = -1024 + (code+48) * 32;
- else if (code >= -64)
- sample = -2048 + (code+64) * 64;
- else if (code >= -80)
- sample = -4096 + (code+80) * 128;
- else if (code >= -96)
- sample = -8192 + (code+96) * 256;
- else if (code >= -112)
- sample = -16384 + (code+112) * 512;
- else
- sample = -32768 + (code+128) * 1024;
-
- return sample;
- }
-
-
- static U8 Sample2ALaw( S16 sample )
- {
- S16 code;
-
- /* Gradient equations (Steigungsgleichungen) */
- if (sample >= 16384)
- code = 112 + (sample-16384) / 1024;
- else if (sample >= 8192)
- code = 96 + (sample-8192) / 512;
- else if (sample >= 4096)
- code = 80 + (sample-4096) / 256;
- else if (sample >= 2048)
- code = 64 + (sample-2048) / 128;
- else if (sample >= 1024)
- code = 48 + (sample-1024) / 64;
- else if (sample >= 512)
- code = 32 + (sample-512) / 32;
- else if (sample >= -512)
- code = -32 + (sample+512) / 16;
- else if (sample >= -1024)
- code = -48 + (sample+1024) / 32;
- else if (sample >= -2048)
- code = -64 + (sample+2048) / 64;
- else if (sample >= -4096)
- code = -80 + (sample+4096) / 128;
- else if (sample >= -8192)
- code = -96 + (sample+8192) / 256;
- else if (sample >= -16384)
- code = -112 + (sample+16384) / 512;
- else
- code = -128 + (sample+32768) / 1024;
-
- /* Positive <-> Negative: */
- if(code < 0) /* negative A-Law range */
- code = ~code;
- else /* positive A-Law range */
- code |= 0x80;
-
- /* Invert even bits: */
- code ^= 0x55;
-
- /* Revert bit order */
- code = (code<<4 & 0xf0) | (code>>4 & 0x0f);
- code = (code<<2 & 0xcc) | (code>>2 & 0x33);
- code = (code<<1 & 0xaa) | (code>>1 & 0x55);
-
- return (U8)code;
- }
-
-
- /****** ALAW_Init ***********************************************************
- *
- * NAME
- * ALAW_Init -- Initialize the ALAW module
- *
- * SYNOPSIS
- * ALAW_Init()
- *
- * VOID ALAW_Init( VOID );
- *
- * FUNCTION
- * Call this once before any other ALAW function.
- *
- * INPUTS
- *
- * RESULTS
- *
- * SEE ALSO
- * ALAW_Exit()
- *
- ****************************************************************************/
-
- VOID
- ALAW_Init( VOID )
- {
- ALAW_Exit();
-
- if (table_alaw_to_16bit = OS_Malloc( 256 * sizeof( S16 ) ))
- {
- S16 *ptr = table_alaw_to_16bit, i;
-
- for (i = 0; i < 256; ++i, ++ptr)
- *ptr = ALaw2Sample( i );
- }
-
- if (table_16bit_to_alaw = OS_Malloc( 65536 * sizeof( U8 ) ))
- {
- U8 *ptr = table_16bit_to_alaw;
- S32 i;
-
- for (i = 0; i < 65536L; ++i, ++ptr)
- *ptr = Sample2ALaw( (S16)i );
- }
- }
-
-
- /****** ALAW_Exit ***********************************************************
- *
- * NAME
- * ALAW_Exit -- Clean up the ALAW module
- *
- * SYNOPSIS
- * ALAW_Exit()
- *
- * VOID ALAW_Exit( VOID );
- *
- * FUNCTION
- * Call this once at the end.
- *
- * INPUTS
- *
- * RESULTS
- *
- * SEE ALSO
- * ALAW_Exit()
- *
- ****************************************************************************/
-
- VOID
- ALAW_Exit( VOID )
- {
- if (table_alaw_to_16bit)
- {
- OS_Free( table_alaw_to_16bit );
- table_alaw_to_16bit = NULL;
- }
-
- if (table_16bit_to_alaw)
- {
- OS_Free( table_16bit_to_alaw );
- table_16bit_to_alaw = NULL;
- }
- }
-
-
- /****** ALAW_ALawTo16Bit ****************************************************
- *
- * NAME
- * ALAW_ALawTo16Bit -- Convert A-Law audio to 16 bit linear format
- *
- * SYNOPSIS
- * ALAW_ALawTo16Bit( from, to, size )
- *
- * void ALAW_ALawTo16Bit( U8 *, S16 *, U32 );
- *
- * FUNCTION
- * Convert A-Law audio to 16 bit linear S16s.
- *
- * INPUTS
- *
- * RESULTS
- *
- * SEE ALSO
- * ALAW_16BitToALaw()
- *
- ****************************************************************************/
-
- VOID
- ALAW_ALawTo16Bit( U8 *alaw, S16 *dest, U32 size )
- {
- U8 *send = alaw + size;
-
- while (alaw < send)
- {
- *dest++ = table_alaw_to_16bit[*alaw++];
- }
- }
-
-
- /****** ALAW_16BitToALaw ****************************************************
- *
- * NAME
- * ALAW_16BitToALaw -- Convert 16 bit linear format to A-Law audio
- *
- * SYNOPSIS
- * ALAW_16BitToALaw( from, to, size )
- *
- * void ALAW_16BitToALaw( S16 *, U8 *, U32 );
- *
- * FUNCTION
- * Convert 16 bit linear signed to A-Law
- *
- * INPUTS
- *
- * RESULTS
- *
- * SEE ALSO
- * ALAW_ALawTo16Bit()
- *
- ****************************************************************************/
-
- VOID
- ALAW_16BitToALaw( S16 *from, U8 *alaw, U32 size )
- {
- U8 *dend = alaw + size;
-
- while (alaw < dend)
- {
- *alaw++ = table_16bit_to_alaw[(U16)*from++];
- }
- }
-
-
-